using System;
using System.IO;
using System.Collections.Generic;
using System.Net.Mail;
using System.Text;

namespace sendmail
{
	class MainClass
	{
		static void PrintHelp ()
		{
			Console.Write (@" sendmail parameters help
-----------------------------------------------------------------
 *	from		""Display Name<me@mail.org>"" or jast me@mail.ru
 * 	to		""Display Name<him@mail.org>"" or jast him@mail.ru
 *	reply		""Display Name<newone@mail.org>"" or jast newone@mail.ru
 * 	smtp 		smtp.gmail.com:587
 * 	ssl		if contains - ssl enabled
 * 	user		account for authenticate 
 * 	pwd		password for authenticate

 * 	subject		subject of the message
 * 	body		text of body or file path with body text
 * 	fileenc		file encoding - name or codepage(Ex: UTF-8 or 1252)
 * 	html		indicate that body is html
-----------------------------------------------------------------
");
			
		}
		public static void Main (string[] args)
		{
			
			var parameters = new List<string> (args);
			
			if (ContainArg ("help", parameters)) {
				PrintHelp ();
				return;
			}
			
			try {
				
				//smtp server settings
				//
				SmtpClient smtp = new SmtpClient ();
				string smtpserver = FindArg ("smtp", parameters);
				if (String.IsNullOrEmpty (smtpserver))
					throw new ArgumentException ("Empty smtp parameter");
				string[] hostopts = smtpserver.Split (new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
				smtp.Host = hostopts[0];
				if (hostopts.Length > 1)
					smtp.Port = Int32.Parse (hostopts[1]);
				smtp.EnableSsl = ContainArg ("ssl", parameters);
				
				var user = FindArg ("user", parameters);
				var pwd = FindArg ("pwd", parameters);
				if (!String.IsNullOrEmpty (user)) {
					//smtp.UseDefaultCredentials = false;
					smtp.Credentials = new System.Net.NetworkCredential (user, pwd);
				} else
					//smtp.UseDefaultCredentials = true;
					smtp.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
				
				//addresses
				//
				MailAddress _from = GetAddress ("from", parameters);
				if (_from == null)
					throw new ArgumentException ("Empty from parameter");
				
				MailAddress _to = GetAddress ("to", parameters);
				if (_to == null)
					throw new ArgumentException ("Empty to parameter");
				
				MailAddress _replyto = GetAddress ("reply", parameters);
				
				//message
				//
				string subject = FindArg ("subject", parameters);
				string body = FindArg ("body", parameters);
				if (File.Exists (body)) {
					System.Text.Encoding enc = Encoding.ASCII;
					string fileenc = FindArg ("fileenc", parameters);
					if (!String.IsNullOrEmpty (fileenc)) {
						int codepage = -1;
						if (Int32.TryParse (fileenc, out codepage))
							enc = Encoding.GetEncoding (codepage);
						else
							enc = Encoding.GetEncoding (fileenc) ?? Encoding.ASCII;
					}
					body = File.ReadAllText (body, enc);
				}
				MailMessage message = new MailMessage ();
				
				message.From = _from;
				message.To.Add (_to);
				if (_replyto != null)
					message.ReplyTo = _replyto;
				message.Subject = subject;
				message.Body = body;
				message.IsBodyHtml = ContainArg ("html", parameters);
				
				Console.WriteLine (String.Format ("sending to {0} with {1}...", _from, smtpserver));
				//sending
				//
				smtp.Send (message);
				
				Console.WriteLine ("sending ok!");
				
			} catch (Exception exc) {
				Console.WriteLine (exc.ToString ());
				
			}
		}
		static bool GetBool (string name, List<string> args)
		{
			var val = FindArg (name, args);
			return String.Equals ("1", val) || String.Equals ("true", val, StringComparison.InvariantCultureIgnoreCase);
		}
		static MailAddress GetAddress (string name, List<string> args)
		{
			string address = FindArg (name, args);
			if (String.IsNullOrEmpty (address))
				return null;
			
			return FormatMailAddress (address);
		}
		static MailAddress FormatMailAddress (string address)
		{
			if (String.IsNullOrEmpty (address))
				return null;
			string email = address, name = null;
			
			if (address.EndsWith (">") && address.LastIndexOf ("<") != -1) {
				email = address.Substring (address.LastIndexOf ("<") + 1, address.Length - 2 - address.LastIndexOf ("<"));
				name = address.Substring (0, address.LastIndexOf ("<"));
			}
			
			return new MailAddress (email, name);
		}
		static bool ContainArg (string name, List<string> args)
		{
			return args.Contains (name);
		}
		static string FindArg (string argname, List<string> args)
		{
			var param = args.Find (arg => arg.StartsWith (argname + "="));
			if (param != null) {
				var val = param.Substring ((argname + "=").Length);
				if (val.StartsWith ("\"") && val.EndsWith ("\""))
					val = val.Substring (1, val.Length - 1);
				return val;
			} else
				return null;
		}
	}
	
	
}

